home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / libdump / ole.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-24  |  20.1 KB  |  640 lines

  1. /*  ole.c  --  object library engine  */
  2.  
  3. #include <stdio.h>
  4. #include <io.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include "ole.h"
  8. #include "svc.h"
  9.  
  10. typedef struct {
  11.                 unsigned char symboldictblock[DICTBLOCKSIZE];   /* symbol dictionary block */
  12.                 int freespaceidx;                               /* cursor to next free symbol space slot */
  13.                 BOOL isfull;                                    /* is this symb. dict. block full ? */
  14.                 int blocknumber;                                /* current block number */
  15.               } DICTBLOCK;
  16.  
  17. /*  The number of pages in the symbol dictionary has to be prime <= 251
  18.     NB. The smallest apge number in MS LIB is 2, in Borland TLIB is 1
  19. */
  20. static int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
  21.                         47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103,
  22.                         107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
  23.                         167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 
  24.                         229, 233, 239, 241, 251 };
  25.  
  26. /* symbol dictionary block */
  27. DICTBLOCK dictblock;
  28.  
  29.  
  30. /*----------------------------------------------------------------------------------
  31.     FUNCTION       : getlibheader
  32.  
  33.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  34.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  35.                        "OBJ Library Management"  -- Thomas Siering
  36.  
  37.     PURPOSE        : gets the header of an object module library
  38.  
  39.     ALGORITHM      :
  40.  
  41.     PARAMETERS     :
  42.  
  43.     RETURNS        :
  44.  
  45.     FUNCTION CALLS :
  46.  
  47.     USAGE          :
  48. --------------------------------------------------------------------------------------*/
  49. void getlibheader(LIBHDR *libheader, FILE *inlibfh)
  50. {
  51.   if (fgetc(inlibfh) != LIBHEADER)
  52.      output(error, NOFILE, "Bogus library header\n");
  53.  
  54.   /* NB.  the LIBHDR data structure has been enlarged to include more info
  55.           than the actual lib. header contains. As a result, a few more bytes
  56.           are read in past the actual header when we take sizeof(LIBHDR). This
  57.           is no problem as there is plenty to read after the header anyway!
  58.   */
  59.  
  60.   if (fread(libheader, sizeof(LIBHDR), 1, inlibfh) != 1)
  61.      output(error, NOFILE, "Couldn't read library header\n");
  62.  
  63.   /* add in header length and checksum byte */
  64.   libheader->pagesize += 3;
  65.  
  66.   /* determine if lib. include MS' libmod extension */
  67.   /* find the first OBJ module in the lib file */
  68.   if (fseek(inlibfh, (long) libheader->pagesize, SEEK_SET) != 0)
  69.      output(error, NOFILE, "Seek for first object module failed\n");
  70.   libheader->islibmodformat = findlibmod(inlibfh);
  71.   libheader->iscasesensitive = (libheader->flags == 0x01) ? TRUE : FALSE;
  72.  
  73.   /* make it clear that we haven't read symbol dictionary yet */
  74.   dictblock.blocknumber = UNDEFINED;
  75.  
  76.   return;
  77. }
  78.  
  79.  
  80. /*----------------------------------------------------------------------------------
  81.     FUNCTION       : findmodule
  82.  
  83.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  84.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  85.                        "OBJ Library Management"  -- Thomas Siering
  86.  
  87.     PURPOSE        :
  88.  
  89.     ALGORITHM      :
  90.  
  91.     PARAMETERS     :
  92.  
  93.     RETURNS        :
  94.  
  95.     FUNCTION CALLS :
  96.  
  97.     USAGE          :
  98. --------------------------------------------------------------------------------------*/
  99. long findmodule(char *modulename, LIBHDR *libheader, FILE *inlibfh)
  100. {
  101.   char *objname;
  102.   DICTENTRY dictentry;
  103.   char *extp;
  104.  
  105.   /* allow extra space for terminating "1!\0" */
  106.   if ((objname = (char *) malloc(strlen(modulename) + 2)) == NULL)
  107.      output(error, NOFILE, "OBJ name memory allocation failed\n");
  108.   strcpy(objname, modulename);
  109.  
  110.   /* allow search for module name xxx.obj */
  111.   if ((extp = strrchr(objname, '.')) != NULL)
  112.      *extp = '\0';
  113.   /* NB. module names are stored in libraries terminated by '!' */
  114.   strcat(objname, "!");
  115.   dictentry = findsymbol(objname, libheader, inlibfh);
  116.  
  117.   free(objname);
  118.   return (dictentry.isfound == TRUE) ? dictentry.modulefilepos : -1L;
  119. }
  120.  
  121.  
  122. /*----------------------------------------------------------------------------------
  123.     FUNCTION       : findsymbol
  124.  
  125.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  126.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  127.                        "OBJ Library Management"  -- Thomas Siering
  128.  
  129.     PURPOSE        :
  130.  
  131.     ALGORITHM      :
  132.  
  133.     PARAMETERS     :
  134.  
  135.     RETURNS        :
  136.  
  137.     FUNCTION CALLS :
  138.  
  139.     USAGE          :
  140. --------------------------------------------------------------------------------------*/
  141. DICTENTRY findsymbol(char *symbolz, LIBHDR *libheader, FILE *inlibfh)
  142. {
  143.   DICTENTRY dictentry;
  144.   char *symbolp;
  145.   hasht hashval;
  146.   int maxtries;
  147.   int block, bucket;
  148.  
  149.   hashval = hash(symbolz, libheader->numdictblocks);
  150.   block = hashval.blockhash;
  151.   bucket = hashval.buckethash;
  152.   maxtries = libheader->numdictblocks * NUMBUCKETS;
  153.   dictentry.isfound = FALSE;
  154.  
  155.   while (maxtries--)
  156.    {
  157.      dictentry = getsymdictentry(block, bucket, libheader, inlibfh);
  158.  
  159.      /* Three alternatives to check after the symbol dictionary lookup : */
  160.  
  161.      /*     1. if the entry is zero, but the dictionary block is NOT full,
  162.                the symbol is not present
  163.      */
  164.      if ((dictentry.isfound == FALSE) && (dictblock.isfull == FALSE))
  165.         return dictentry;
  166.  
  167.      /*     2. if the entry is zero, and the dictionary block is full, the
  168.                symbol may have been rehashed to another bloc - keep looking
  169.  
  170.             3. if the entry is non-zero, we still have to verify the symbol.
  171.                if it is the wrong one (hash clash), keep looking
  172.      */
  173.      if (dictentry.isfound == TRUE)
  174.       {
  175.         /* get the symbol name */
  176.         symbolp = makeasciiz(dictentry.symbolp);
  177.  
  178.         /* choose case-sensitive or insensitive comparison as appropriate */
  179.         if ((libheader->iscasesensitive == TRUE) ? strcmp(symbolz, symbolp) : stricmp(symbolz, symbolp) == STR_EQUAL)
  180.          {
  181.            free(symbolp);
  182.            return dictentry;
  183.          }
  184.  
  185.         free(symbolp);
  186.       }
  187.  
  188.      /* cases 2 & 3 (without a symbol match) require a rehash */
  189.      block += hashval.blockovfl;
  190.      bucket += hashval.bucketovfl;
  191.      block %= libheader->numdictblocks;
  192.      bucket %= NUMBUCKETS;
  193.    }
  194.  
  195.   /* we never found the entry */
  196.   dictentry.isfound = FALSE;
  197.   return (dictentry);
  198. }
  199.  
  200.  
  201. /*----------------------------------------------------------------------------------
  202.     FUNCTION       : hash
  203.  
  204.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  205.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  206.                        "OBJ Library Management"  -- Thomas Siering
  207.  
  208.     PURPOSE        :
  209.  
  210.     ALGORITHM      :
  211.  
  212.     PARAMETERS     :
  213.  
  214.     RETURNS        :
  215.  
  216.     FUNCTION CALLS :
  217.  
  218.     USAGE          :
  219. --------------------------------------------------------------------------------------*/
  220. hasht hash(char symbolz[], int numhashblocks)
  221. {
  222.   hasht symhash;                            /* the resulting aggregate hash values */
  223.   unsigned char *symbolc;                   /* symbol with prepended count */
  224.   int symlength;                            /* length of symbol to be hashed */
  225.   unsigned char *fwdp, *bwdp;               /* temp ptrs to string : forward/backward */
  226.   unsigned int fwdc, bwdc;                  /* current chars at fwd/backwd pointers */
  227.   unsigned int blockh, blockd, bucketh,
  228.                bucketd;                     /* temporary values */
  229.   int i;
  230.  
  231.   symlength = strlen(symbolz);
  232.  
  233.   /* make symbol string in length byte/ASCII string format */
  234.   if ((symbolc = malloc(symlength + 2)) == NULL)
  235.      output(error, NOFILE, "Memory allocation failed\n");
  236.   symbolc[0] = (unsigned char) symlength;
  237.  
  238.   /* copy without EOS */
  239.   strncpy((signed char *) &symbolc[1], symbolz, symlength + 1);
  240.   fwdp = &symbolc[0];
  241.   bwdp = &symbolc[symlength];
  242.   blockh = blockd = bucketh = bucketd = 0;
  243.  
  244.   for (i = 0; i < symlength; i++)
  245.    {
  246.      /* hashing is done case-insensitive, including the length byte */
  247.      fwdc = (unsigned int) *fwdp++ | 0x20;;
  248.      bwdc = (unsigned int) *bwdp++ | 0x20;
  249.  
  250.      /* XOR the current character (moving forward or reverse, depending on
  251.         the variable calculated) with the intermediate result rotated by
  252.         2 bits (again, left or right depending on variable)
  253.      */
  254.      /* block hash : traverse forward, rotate left */
  255.      blockh = fwdc ^ ROL(blockh, 2);
  256.      /* block overflow delta : traverse reverse, rotate left */
  257.      blockd = bwdc ^ ROL(blockd, 2);
  258.      /* bucket hash : traverse reverse, rotate right */
  259.      bucketh = bwdc ^ ROR(bucketh, 2);
  260.      /* bucket overflow delta : traverse forward, rotate right */
  261.      bucketd = fwdc ^ ROR(bucketd, 2);
  262.    }
  263.  
  264.   /* NB. results are zero-based */
  265.   symhash.blockhash = blockh % numhashblocks;
  266.   symhash.buckethash = bucketh % NUMBUCKETS;
  267.  
  268.   /* obviously, has deltas of zero would be nonsense */
  269.   symhash.blockovfl = max(blockd % numhashblocks, 1);
  270.   symhash.bucketovfl = max(bucketd % NUMBUCKETS, 1);
  271.  
  272.   free(symbolc);
  273.   return (symhash);
  274. }
  275.  
  276.  
  277. /*----------------------------------------------------------------------------------
  278.     FUNCTION       : getsymdictblock
  279.  
  280.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  281.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  282.                        "OBJ Library Management"  -- Thomas Siering
  283.  
  284.     PURPOSE        :
  285.  
  286.     ALGORITHM      :
  287.  
  288.     PARAMETERS     :
  289.  
  290.     RETURNS        :
  291.  
  292.     FUNCTION CALLS :
  293.  
  294.     USAGE          :
  295. --------------------------------------------------------------------------------------*/
  296. void getsymdictblock(int blocknumber, LIBHDR *libheader, FILE *inlibfh)
  297. {
  298.  
  299.   /* find and read the whole symbol dictionary block */
  300.   if (fseek(inlibfh, libheader->dictionaryoffset + (long) blocknumber * (long) DICTBLOCKSIZE, SEEK_SET) != 0)
  301.      output(error, NOFILE, "Could not find symbol dictionary\n");
  302.  
  303.   if (fread(dictblock.symboldictblock, DICTBLOCKSIZE, 1, inlibfh) != 1)
  304.      output(error, NOFILE, "Couldn't read library header\n");
  305.  
  306.   /* is this block all used up ? */
  307.   dictblock.freespaceidx = dictblock.symboldictblock[NUMBUCKETS];
  308.   dictblock.isfull = (dictblock.freespaceidx == DICTBLKFULL) ? TRUE : FALSE;
  309.  
  310.   /* for future reference, remember block number */
  311.   dictblock.blocknumber = blocknumber;
  312.  
  313.   return;
  314. }
  315.  
  316.  
  317. /*----------------------------------------------------------------------------------
  318.     FUNCTION       : getsymdictentry
  319.  
  320.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  321.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  322.                        "OBJ Library Management"  -- Thomas Siering
  323.  
  324.     PURPOSE        :
  325.  
  326.     ALGORITHM      :
  327.  
  328.     PARAMETERS     :
  329.  
  330.     RETURNS        :
  331.  
  332.     FUNCTION CALLS :
  333.  
  334.     USAGE          :
  335. --------------------------------------------------------------------------------------*/
  336. DICTENTRY getsymdictentry(int blocknumber, int bucketnumber, LIBHDR *libheader, FILE *inlibfh)
  337. {
  338.   DICTENTRY dictentry;
  339.   unsigned char symboloffset;
  340.   unsigned char symbollength;
  341.   int pagenumber;
  342.  
  343.   /* remember entry's block/bucket, and initialise to no (NULL) entry */
  344.   dictentry.blocknumber = blocknumber;
  345.   dictentry.bucketnumber = bucketnumber;
  346.   dictentry.symbolp = NULL;
  347.   dictentry.isfound = FALSE;
  348.  
  349.   /* make sure the appropriate block was already read from .obj mod. library */
  350.   if (dictblock.blocknumber != blocknumber)
  351.      getsymdictblock(blocknumber, libheader, inlibfh);
  352.  
  353.   /* WORD offset of symbol in dictionary block (0 means no entry) */
  354.   symboloffset = dictblock.symboldictblock[bucketnumber];
  355.   if (symboloffset != 0)
  356.    {
  357.      /* since it is a word offsedt, need to multiply by 2 */
  358.      dictentry.symbolp = &dictblock.symboldictblock[symboloffset * 2];
  359.  
  360.      /* get the symbol's object module offset in lib. */
  361.      symbollength = *dictentry.symbolp;
  362.  
  363.      /* object module's lib. page number is right after symbol string */
  364.      pagenumber = *(int *) (dictentry.symbolp + symbollength + 1);
  365.      dictentry.modulefilepos = (long) pagenumber * (long) libheader->pagesize;
  366.      dictentry.isfound = TRUE;
  367.    }
  368.  
  369.   return dictentry;
  370. }
  371.  
  372.  
  373. /*----------------------------------------------------------------------------------
  374.     FUNCTION       : getmodulename
  375.  
  376.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  377.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  378.                        "OBJ Library Management"  -- Thomas Siering
  379.  
  380.     PURPOSE        :
  381.  
  382.     ALGORITHM      :
  383.  
  384.     PARAMETERS     :
  385.  
  386.     RETURNS        :
  387.  
  388.     FUNCTION CALLS :
  389.  
  390.     USAGE          :
  391. --------------------------------------------------------------------------------------*/
  392. char *getmodulename(long modulefilepos, LIBHDR *libheader, FILE *inlibfh)
  393. {
  394.   int symbollength;
  395.   char *modulename;
  396.   OMFHEADER omfheader;
  397.  
  398.   /* position at beginning of pertinent object module */
  399.   if (fseek(inlibfh, modulefilepos, SEEK_SET) != 0)
  400.      output(error, NOFILE, "seek for object module at %lx failed\n", modulefilepos);
  401.  
  402.   if (libheader->islibmodformat == FALSE)
  403.    {
  404.      if (fread(&omfheader, sizeof(omfheader), 1, inlibfh) != 1)
  405.         output(error, NOFILE, "Couldn't read THEADR at %lx\n", modulefilepos);
  406.      if (omfheader.rectype != THEADR)
  407.         output(error, NOFILE, "Bogus THEADR OMF record at %lx\n", modulefilepos);
  408.    }
  409.   else
  410.      if (findlibmod(inlibfh) == FALSE)
  411.       {
  412.         output(warning, NOFILE, "No LIBMOD record found at %lx\n", modulefilepos);
  413.         return NULL;
  414.       }
  415.  
  416.   symbollength = fgetc(inlibfh);
  417.   if ((modulename = (char *) malloc(symbollength + 1)) == NULL)
  418.      output(error, NOFILE, "MALLOC failure reading module name\n");
  419.   if (fread(modulename, symbollength, 1, inlibfh) != 1)
  420.      output(error, NOFILE, "Couldn't read THREADR\n");
  421.   modulename[symbollength] = '\0';
  422.  
  423.   return modulename;
  424. }
  425.  
  426.  
  427. /*----------------------------------------------------------------------------------
  428.     FUNCTION       : findlibmod
  429.  
  430.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  431.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  432.                        "OBJ Library Management"  -- Thomas Siering
  433.  
  434.     PURPOSE        :
  435.  
  436.     ALGORITHM      :
  437.  
  438.     PARAMETERS     :
  439.  
  440.     RETURNS        :
  441.  
  442.     FUNCTION CALLS :
  443.  
  444.     USAGE          :
  445. --------------------------------------------------------------------------------------*/
  446. BOOL findlibmod(FILE *inlibfh)
  447. {
  448.   COMMENTHEADER commenthdr;
  449.  
  450.   /* search (up to) all COMENT records in OBJ module */
  451.   while (findobjrecord(inlibfh, COMENT) == TRUE)
  452.    {
  453.      if (fread(&commenthdr, sizeof(commenthdr), 1, inlibfh) != 1)
  454.         output(error, NOFILE, "Couldn't read OBJ\n");
  455.      if (commenthdr.commentclass == LIBMOD)
  456.         return TRUE;
  457.      else
  458.         /* if not found : forward to next record and retry */
  459.         if (fseek(inlibfh, (long) commenthdr.reclength - sizeof(commenthdr) + sizeof(OMFHEADER), SEEK_SET) != 0)
  460.            output(error, NOFILE, "Seek try for LIBMOD failed\n");
  461.    }
  462.  
  463.   /* we got here only if COMENT of class LIBMOD was never found */
  464.   return FALSE;
  465. }
  466.  
  467.  
  468.  
  469. /*----------------------------------------------------------------------------------
  470.     FUNCTION       : findobjrecord
  471.  
  472.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  473.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  474.                        "OBJ Library Management"  -- Thomas Siering
  475.  
  476.     PURPOSE        :
  477.  
  478.     ALGORITHM      :
  479.  
  480.     PARAMETERS     :
  481.  
  482.     RETURNS        :
  483.  
  484.     FUNCTION CALLS :
  485.  
  486.     USAGE          :
  487. --------------------------------------------------------------------------------------*/
  488. BOOL findobjrecord(FILE *objfh, unsigned char rectype)
  489. {
  490.   OMFHEADER objheader;
  491.  
  492.   while (fread(&objheader, sizeof(objheader), 1, objfh) == 1)
  493.    {
  494.      /* if is is the record type we are looking for, we're done */
  495.      if (objheader.rectype == rectype)
  496.       {
  497.         /* return with obj module set to record requested */
  498.         if (fseek(objfh, -(long) sizeof(objheader), SEEK_CUR) != 0)
  499.            output(error, NOFILE, "Seek for record type %02x failed\n", rectype & 0xff);
  500.         return TRUE;
  501.       }
  502.  
  503.      /* end of object module, record type NEVER found */
  504.      if (objheader.rectype == MODEND)
  505.         return FALSE;
  506.  
  507.      /* forward file pointer to next object module record */
  508.      if (fseek(objfh, (long) objheader.reclength, SEEK_CUR) != 0)
  509.         output(error, NOFILE, "Seek retry for record type %02x failed\n", rectype & 0xff);
  510.    }
  511.  
  512.   /* if this quit due to I/O condition, its either EOF or I/O error */
  513.   if (feof(objfh) == 0)
  514.      output(error, NOFILE, "Couldn't read OBJ\n");
  515.  
  516.   /* we completed without error and without finding the record (should NEVER happen) */
  517.   return FALSE;
  518. }
  519.  
  520.  
  521. /*----------------------------------------------------------------------------------
  522.     FUNCTION       : extractmodule
  523.  
  524.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  525.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  526.                        "OBJ Library Management"  -- Thomas Siering
  527.  
  528.     PURPOSE        :
  529.  
  530.     ALGORITHM      :
  531.  
  532.     PARAMETERS     :
  533.  
  534.     RETURNS        :
  535.  
  536.     FUNCTION CALLS :
  537.  
  538.     USAGE          :
  539. --------------------------------------------------------------------------------------*/
  540. BOOL extractmodule(char *modulename, char *newmodulename, LIBHDR *libheader, FILE *inlibfh)
  541. {
  542.   long filepos;
  543.   char *newobjp;
  544.   char *newobjname;
  545.   FILE *newobjfh;
  546.  
  547.   /* find the object module's position in the library file */
  548.   filepos = findmodule(modulename, libheader, inlibfh);
  549.   if (filepos == -1L)
  550.      return FALSE;
  551.  
  552.   /* determine the name for the new obj, and set it up */
  553.   newobjp = (newmodulename != NULL) ? newmodulename : modulename;
  554.   if ((newobjname = (char *) malloc(strlen(newobjp) + 5)) == NULL)
  555.      output(error, NOFILE, "MALLOC failure making module name\n");
  556.   strcpy(newobjname, newobjp);
  557.  
  558.   /* open the new .obj file, and pass everything off to a low-level routine */
  559.   if ((newobjfh = fopen(newobjname, "wb")) == NULL)
  560.      output(error, NOFILE, "Failure opening new module file\n");
  561.  
  562.   copyobjmodule(newobjfh, filepos, inlibfh);
  563.  
  564.   fclose(newobjfh);
  565.   free(newobjname);
  566.   return TRUE;
  567. }
  568.  
  569.  
  570. /*----------------------------------------------------------------------------------
  571.     FUNCTION       : copyobjmodule
  572.  
  573.     PROGRAMMER     : Glen Downton           VERSION : 01   DATE : Nov 17,1991
  574.                        Originally published in Dr. Dobb's Journal (Sep. 1991)
  575.                        "OBJ Library Management"  -- Thomas Siering
  576.  
  577.     PURPOSE        :
  578.  
  579.     ALGORITHM      :
  580.  
  581.     PARAMETERS     :
  582.  
  583.     RETURNS        :
  584.  
  585.     FUNCTION CALLS :
  586.  
  587.     USAGE          :
  588. --------------------------------------------------------------------------------------*/
  589. void copyobjmodule(FILE *newobjfh, long filepos, FILE *inlibfh)
  590. {
  591.   OMFHEADER rechdr;
  592.  
  593.   /* get to the object module in LIB */
  594.   if (fseek(inlibfh, filepos, SEEK_SET) != 0)
  595.      output(error, NOFILE, "Seek failure to file position %ld\n", filepos);
  596.  
  597.   /* write module from LIB to separate obj file */
  598.   do {
  599.        /* read OMF header record, this will give record type and length */
  600.        if (fread(&rechdr, sizeof(rechdr), 1, inlibfh) != 1)
  601.           output(error, NOFILE, "Couldn't read OBJ\n");
  602.  
  603.        /* need to check every COMENT record to make sure to strip LIBMOD out */
  604.        if (rechdr.rectype == COMENT)
  605.         {
  606.           /* throw out next byte (attrib COMENT byte) for now */
  607.           fgetc(inlibfh);
  608.  
  609.           /* check COMENT's comment class
  610.              if it is a LIBMOD, set file pointer to next record and continue
  611.           */
  612.           if (fgetc(inlibfh) == LIBMOD)
  613.            {
  614.              if (fseek(inlibfh, (long) rechdr.reclength - 2L, SEEK_CUR) != 0)
  615.                 output(error, NOFILE, "Seek error on COMENT\n");
  616.              continue;
  617.            }
  618.           else
  619.              /* wasn't a LIBMOD : reset file pointer to continue normally */
  620.              if (fseek(inlibfh, -2L, SEEK_CUR) != 0)
  621.                 output(error, NOFILE, "Seek error on COMENT\n");
  622.         }
  623.  
  624.       if (fwrite(&rechdr, sizeof(rechdr), 1, newobjfh) != 1)
  625.          output(error, NOFILE, "Couldn't write new OBJ\n");
  626.  
  627.       while (rechdr.reclength--)
  628.          fputc(fgetc(inlibfh), newobjfh);
  629.  
  630.      } while (rechdr.rectype != MODEND);
  631.  
  632.   return;
  633. }
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.